package com.sukaiyi.giteejavaapi.common.httpendpointfactory;

import cn.hutool.core.io.IoUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.sukaiyi.giteejavaapi.common.HttpEndpoint;
import com.sukaiyi.giteejavaapi.common.HttpEndpointFactory;

import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author sukaiyi
 * @date 2020/06/28
 */
public abstract class AbstractHttpEndpointFactory implements HttpEndpointFactory {

    public List<HttpEndpoint> produce() {
        InputStream is = Optional.of(this)
                .map(AbstractHttpEndpointFactory::conf)
                .map(AbstractHttpEndpointFactory.class.getClassLoader()::getResourceAsStream)
                .orElse(null);
        if (is == null) {
            return Collections.emptyList();
        }
        try {
            List<HttpEndpoint> apis = new ArrayList<>();
            String content = IoUtil.read(is, StandardCharsets.UTF_8);
            JSONArray apiArr = Optional.of(content)
                    .map(JSONUtil::parseObj)
                    .map(e -> e.getJSONArray("apis"))
                    .orElseGet(JSONArray::new);
            for (int i = 0; i < apiArr.size(); i++) {
                JSONObject apiObj = apiArr.getJSONObject(i);
                HttpEndpoint httpEndpoint = new HttpEndpoint();
                httpEndpoint.setName(apiObj.getStr("name"));
                httpEndpoint.setDescription(apiObj.getStr("description"));
                httpEndpoint.setMethod(HttpEndpoint.HttpMethod.valueOf(apiObj.getStr("method")));
                httpEndpoint.setUrl(apiObj.getStr("url"));
                List<HttpEndpoint.Param> params = new ArrayList<>();
                JSONArray parameters = apiObj.getJSONArray("parameters");
                for (int j = 0; j < parameters.size(); j++) {
                    JSONObject parameter = parameters.getJSONObject(j);
                    HttpEndpoint.Param param = new HttpEndpoint.Param();
                    param.setName(parameter.getStr("name"));
                    param.setDescription(parameter.getStr("description"));
                    param.setDataType(HttpEndpoint.ParamDataType.valueOf(parameter.getStr("dataType").toUpperCase()));
                    param.setType(HttpEndpoint.ParamType.valueOf(parameter.getStr("type").toUpperCase()));
                    params.add(param);
                }
                httpEndpoint.setParams(params);
                httpEndpoint.setHeaders(
                        apiObj.getJSONObject("headers").entrySet()
                                .stream()
                                .collect(Collectors.toMap(Map.Entry::getKey, e -> String.valueOf(e.getValue())))
                );
                apis.add(httpEndpoint);
            }
            return apis;
        } finally {
            IoUtil.close(is);
        }
    }

    /**
     * @return 配置文件路径
     */
    protected abstract String conf();
}
